﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;

namespace CommonTools.UserControls
{
    public class HorizontalTick : UserControl
    {
        Pen backpen;
        public double MinValue
        {
            get { return (double)GetValue(MinValueProperty); }
            set { SetValue(MinValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MinValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MinValueProperty =
            DependencyProperty.Register("MinValue", typeof(double), typeof(HorizontalTick), new PropertyMetadata(0.0, new PropertyChangedCallback(RefeshTick)));




        public double MaxValue
        {
            get { return (double)GetValue(MaxValueProperty); }
            set { SetValue(MaxValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MaxValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MaxValueProperty =
            DependencyProperty.Register("MaxValue", typeof(double), typeof(HorizontalTick), new PropertyMetadata(100.0, new PropertyChangedCallback(RefeshTick)));




        public double BigTick
        {
            get { return (double)GetValue(BigTickProperty); }
            set { SetValue(BigTickProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BigTick.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BigTickProperty =
            DependencyProperty.Register("BigTick", typeof(double), typeof(HorizontalTick), new PropertyMetadata(10.0, new PropertyChangedCallback(RefeshTick)));




        public double SmallTick
        {
            get { return (double)GetValue(SmallTickProperty); }
            set { SetValue(SmallTickProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SmallTick.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SmallTickProperty =
            DependencyProperty.Register("SmallTick", typeof(double), typeof(HorizontalTick), new PropertyMetadata(2.0, new PropertyChangedCallback(RefeshTick)));



        public double BigTickLength
        {
            get { return (double)GetValue(BigTickLengthProperty); }
            set { SetValue(BigTickLengthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BigTickLength.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BigTickLengthProperty =
            DependencyProperty.Register("BigTickLength", typeof(double), typeof(HorizontalTick), new PropertyMetadata(10.0, new PropertyChangedCallback(RefeshTick)));




        public double SmallTickLength
        {
            get { return (double)GetValue(SmallTickLengthProperty); }
            set { SetValue(SmallTickLengthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SmallTickLength.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SmallTickLengthProperty =
            DependencyProperty.Register("SmallTickLength", typeof(double), typeof(HorizontalTick), new PropertyMetadata(5.0, new PropertyChangedCallback(RefeshTick)));


        public Brush PenBrush
        {
            get { return (Brush)GetValue(PenBrushProperty); }
            set { SetValue(PenBrushProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PenBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PenBrushProperty =
            DependencyProperty.Register("PenBrush", typeof(Brush), typeof(HorizontalTick), new PropertyMetadata(Brushes.White, (sender, e) =>
            {
                var dp = sender as HorizontalTick;
                if (dp == null) return;
                dp.RefeshPen();
            }));

        public double PenThickness
        {
            get { return (double)GetValue(PenThicknessProperty); }
            set { SetValue(PenThicknessProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PenThickness.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PenThicknessProperty =
            DependencyProperty.Register("PenThickness", typeof(double), typeof(HorizontalTick), new PropertyMetadata(1.0, (sender, e) =>
            {
                var dp = sender as HorizontalTick;
                if (dp == null) return;
                dp.RefeshPen();
            }));

        public HorizontalTick()
        {
            backpen = new Pen(PenBrush, PenThickness);
            backpen.Freeze();
            this.SizeChanged += HorizontalTick_SizeChanged; ;
        }

        private void HorizontalTick_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            InvalidateVisual();
        }

        private void RefeshPen()
        {
            backpen = new Pen(PenBrush, 1);
            backpen.Freeze();
            InvalidateVisual();
        }

        private static void RefeshTick(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var dp = d as HorizontalTick;
            if (dp == null) return;
            dp.InvalidateVisual();
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            if (this.Visibility == Visibility.Collapsed) return;

            drawingContext.DrawLine(backpen, new Point(0, this.ActualHeight), new Point(this.ActualWidth, this.ActualHeight));

            //小刻度
            if (SmallTick > 0)
            {
                var smallTickCount = ActualWidth / SmallTick;
                for (int i = 0; i <= smallTickCount; i++)
                {
                    Point p1 = new Point(i * SmallTick, this.ActualHeight  - PenThickness / 2);
                    Point p2 = new Point(i * SmallTick, this.ActualHeight  - PenThickness / 2 - SmallTickLength);
                    drawingContext.DrawLine(backpen, p1, p2);
                }
            }

            //大刻度
            if (BigTick > 0)
            {
                var bigTickCount = ActualWidth / BigTick;
                for (int i = 0; i <= bigTickCount; i++)
                {
                    Point p1 = new Point(i * BigTick, this.ActualHeight - PenThickness);
                    Point p2 = new Point(i * BigTick, this.ActualHeight - PenThickness - BigTickLength);
                    drawingContext.DrawLine(backpen, p1, p2);
                    FormattedText txt = new FormattedText((BigTick * i + MinValue).ToString(), new System.Globalization.CultureInfo("zh-CHS", false), 
                        FlowDirection.LeftToRight, new Typeface("Microsoft YaHei"), FontSize, PenBrush);
                    drawingContext.DrawText(txt, new Point(p2.X - txt.Width / 2, p2.Y - txt.Height));
                }
            }

            base.OnRender(drawingContext);
        }
    }
}
